﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO.Ports;
using System.Windows.Forms;
using LogLib;

namespace QrCode
{


    public delegate void DisplayDelegate(string ReceiveData);

    public delegate void EventHandler_Comm(byte[] readBuffer);

    class SerialPortHelper
    {
        public event EventHandler_Comm DataReceived;

        public SerialPort serialPort;
        Thread thread;
        volatile bool _keepReading;

        private DisplayDelegate displayDelegate;



        public SerialPortHelper()
        {
            serialPort = new SerialPort();
            thread = null;
            _keepReading = false;
        }

        public bool IsOpen
        {
            get
            {
                return serialPort.IsOpen;
            }
        }

        private void StartReading()
        {
            if (!_keepReading)
            {
                _keepReading = true;
                thread = new Thread(new ThreadStart(ReadPort));
                thread.Start();
            }
        }

        private void StopReading()
        {
            _keepReading = false;
            if (!_keepReading)
            {
                _keepReading = false;
                //thread.Join();
                thread = null;
            }
        }

        private void ReadPort()
        {
            while (_keepReading)
            {
                if (serialPort.IsOpen)
                {
                    int count = -1;
                    Thread.Sleep(30);
                    try
                    {
                        count = serialPort.BytesToRead;
                    }
                    catch
                    { }
                    if (count > 0)
                    {
                        byte[] readBuffer = new byte[count];
                        try
                        {
                            Application.DoEvents();
                            Thread.Sleep(1000);
                            serialPort.Read(readBuffer, 0, count);
                            if (DataReceived != null)
                            {
                                DataReceived(readBuffer);
                            }
                            Thread.Sleep(50);
                        }
                        catch
                        {
                        }
                    }
                }
            }
        }

        public bool Open()
        {
            bool ret = true;
            try
            {
                //Close();
                serialPort.Open();
            }
            catch
            {
                return false;
            }

            if (serialPort.IsOpen)
            {
                //StartReading();

                //绑定委托方法

                displayDelegate = new DisplayDelegate(ReceiveDataHandle);

                //串口接收数据事件绑定

                serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
            }
            else
            {
                ret = false;
            }
            return ret;
        }

        public void Close()
        {
            StopReading();
            serialPort.Close();
        }

        public void WritePort(byte[] send, int offSet, int count)
        {
            if (IsOpen)
            {
                serialPort.Write(send, offSet, count);
            }
        }

        public void WriteFile(string txt)
        {
            if (IsOpen)
            {
                serialPort.WriteLine(txt);
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            string ComRead = null;

            //串口通信过程中，串口实际传输速率并没有模拟的串口速率快，因此需要一定的延时等待传输完成，然后再在缓存中接收数据

            Thread.Sleep(1000);

            //接收数据

            ComRead = Com_Read(serialPort, "ASCII");
            Log.Write("扫描到的二维码：" + ComRead);
            ScanCode.barcodeMsg = ComRead;
        }

        //ReceiveData  接收到的字符串数据

        public void ReceiveDataHandle(String ReceiveData)
        {

            //根据需要写处理代码

        }

        public String Com_Read(SerialPort serialPort, String EncodingRead)
        {

            //开辟接收缓冲区

            byte[] ReDatas = new byte[serialPort.BytesToRead];

            //从串口读取数据

            serialPort.Read(ReDatas, 0, ReDatas.Length);

            //返回字符串

            return AddData(ReDatas, EncodingRead);
        }



        public String AddData(byte[] data, String EncodingRead)
        {
            String ReadText = null;
            //设置发送编码格式
            switch (EncodingRead)
            {
                //16进制
                case "HEX":
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < data.Length; i++)
                    {
                        sb.AppendFormat("{0:x2}" + " ", data[i]);
                    }
                    ReadText = sb.ToString().ToUpper();
                    break;
                //ASCII码
                case "ASCII":
                    ReadText = new ASCIIEncoding().GetString(data);
                    break;
                //UTF8
                case "UTF8":
                    ReadText = new UTF8Encoding().GetString(data);
                    break;
                case "Unicode":
                    ReadText = new UnicodeEncoding().GetString(data);
                    break;
                default:
                    StringBuilder st = new StringBuilder();
                    for (int i = 0; i < data.Length; i++)
                    {
                        st.AppendFormat("{0:x2}" + " ", data[i]);
                    }
                    ReadText = st.ToString().ToUpper();
                    break;
            }
            return ReadText;

        }
    }
}
